﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using DevExpress.Data;
using System.Collections;
namespace ChuanPlus.DAO
{
    class InvoiceDAO
    {
        // dung dafault session //id cua stockcard tu tang, hok dc gan // chua xet redinvQty
        //
        // save an invoice to database, stockCard,stock quantity, update supplier's credit as 1 UnitOfWork
        //
        public static void save(Invoice invoice) // ok
        {
            Session.DefaultSession.BeginTransaction();
            InvoiceDetails invDetail = null;
            Product product = null;
            Stock stockObj = null;
            // lay TransactionType 
            XPQuery<TransactionType> transtype = new XPQuery<TransactionType>(Session.DefaultSession);
            var listTrans = from t in transtype
                            where t.TransactionTypeID == 2
                            select t;
            List<TransactionType> arr = new List<TransactionType>(listTrans.AsEnumerable<TransactionType>());
            TransactionType transtypeObj = arr[0];
            try
            {
                //----------Nhan hang tu supplier------
                //-------------------------------------
                //----------1. Tao stockcard de bit in-out nhu the nao 
                //----------2. Update stock quantity trong bang Product
                //--------------(1 product tuong duong 1 stockcard --- o day 1 InvoiceDetail la 1 stockcard)
                int count = invoice.InvoiceDetails.Count;

                StockCard st;
                for (int i = 0; i < count; i++)
                {
                    //// Cong QtyBalance cho Stock ung voi Product va Warehouse & set balance cho stockcard
                     invDetail = invoice.InvoiceDetails[i];
                     product = invDetail.StockID.ID;
                     stockObj = invDetail.StockID;
                    ///// lay record chua ID va warehouse cu the trong bang Stock
                    //// lay warehouse thich hop (check lai la office or stock)
                    //XPQuery<Warehouse> warehouse = new XPQuery<Warehouse>(Session.DefaultSession);
                    //var list = from w in warehouse
                    //           where w.warehouseId == 2
                    //           select w;
                    //List<Warehouse> arrWarehouse = new List<Warehouse>(list.AsEnumerable<Warehouse>());
                    //Warehouse warehouseObj = arrWarehouse[0];

                    //// lay stockObj co trong db or tao moi
                    //XPQuery<Stock> stock = new XPQuery<Stock>(Session.DefaultSession);
                    //var listStock = from s in stock
                    //                where (s.ID == product && s.warehouseID == warehouseObj)
                    //                select s;
                    //List<Stock> arrStock = new List<Stock>(listStock.AsEnumerable<Stock>());
                    //Stock stockObj;
                    //if (arrStock.Count == 0)
                    //{
                    //    stockObj = new Stock(Session.DefaultSession, product, warehouseObj, 0);
                    //}
                    //else
                    //{
                    //    stockObj = arrStock[0];
                    //}

                    // set QtyBalance va balance cua Stockcard
                    double balance = stockObj.QtyBalance + invDetail.Quantity;
                    stockObj.QtyBalance = balance;
                    stockObj.Save();

                    //xet hoa don do, cong dzo bang Product
                    double redInvQty;
                    if (product.DistributorID.DistributorName.Equals("CBD"))
                    {
                        redInvQty = 0;
                    }
                    else
                    {
                        redInvQty = invDetail.Quantity;
                    }
                    product.RedInvQty += redInvQty;
                    product.Save();
                    //luu stockcard
                    long StockCardID = StockCardDAO.GenerateId();
                    st = new StockCard(Session.DefaultSession, ++StockCardID, stockObj, invoice.InvoiceDate, invDetail.Quantity, 0.0f, balance, transtypeObj, invoice.InvoiceNo);
                    st.Save();
                }
                //----------3. Cong dept dzo cho Supplier------ ko co field credit ???
                invoice.SupplierID.SupplierDebt += invoice.Total;
                invoice.SupplierID.Save();
                invoice.Status = "P";
                //----------4. luu Invoice dzo database (tu dong luu InvoiceDetail theo)
                invoice.Save();

                Session.DefaultSession.CommitTransaction();
                
            }
            catch (Exception e)
            {
                Session.DefaultSession.RollbackTransaction();
                throw new Exception(e.Message);
            }
            //return "";

        }
        public static List<Invoice> getInvoices(string status)
        {
            try
            {
                XPQuery<Invoice> invoice = new XPQuery<Invoice>(Session.DefaultSession);
                var list = from i in invoice
                           where i.Status == status
                           select i;
                return new List<Invoice>(list.AsEnumerable<Invoice>());
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
                
            }
        }
        //
        // update an invoice to database, stockCard, stock quantity update supplier's credit as 1 UnitOfWork
        // y chang cai save (OMG) :D
        public static bool update(Invoice invoice)
        {
            return true;
        }
        public static List<Invoice> GetAllInvoices() //ok
        {
            Session session = new Session();
            XPQuery<Invoice> invoices = new XPQuery<Invoice>(session);
            var list = from inv in invoices
                       select inv;
            List<Invoice> arr = new List<Invoice>(list.AsEnumerable<Invoice>());
            try
            {
                return arr;
            }
            catch
            {
                return null;
            }
        }
        //
        //return list of invoice by InvoiceDate
        //order by InvoiceDate DESC
        public static List<Invoice> GetInvoiceByDate(DateTime d) //ok
        {
            Session session = new Session();
            XPQuery<Invoice> invoices = new XPQuery<Invoice>(session);
            var list = from inv in invoices
                       where inv.InvoiceDate == d
                       orderby inv.InvoiceDate descending
                       select inv;
            List<Invoice> arr = new List<Invoice>(list.AsEnumerable<Invoice>());
            try
            {
                return arr;
            }
            catch
            {
                return null;
            }
        }
        //
        //return list of invoice by InvoiceDate base on month of year
        // order by InvoiceDate DESC
        public static List<Invoice> GetInvoiceByMonth(DateTime d) // this method doesnot support !!! Loi o cho ToString("MM")
        {
            //Session session = new Session();
            //XPQuery<Invoice> invoices = new XPQuery<Invoice>(session);
            //var list = from i in invoices
            //           where i.InvoiceDate.ToString("MM") == d.ToString("MM")
            //           select i;
            //List<Invoice> arr = new List<Invoice>(list.AsEnumerable<Invoice>());

            //try
            //{
            //    return arr;
            //}
            //catch (Exception e)
            //{
            //    return null;
            //}
            return null;
        }
        //
        //return list of invoice by InvoiceDate base on Invoice Number
        // order by InvoiceDate DESC
        public static Invoice GetInvoiceByNo(string InvoiceNo) //ok
        {
            Session session = new Session();
            XPQuery<Invoice> invoices = new XPQuery<Invoice>(session);
            var list = from i in invoices
                       where (i.InvoiceNo == InvoiceNo)
                       orderby i.InvoiceDate descending
                       select i;
            List<Invoice> arr = new List<Invoice>(list.AsEnumerable<Invoice>());
            try
            {
                return arr[0];
            }
            catch 
            {
                return null;
            }
        }
        /// <summary>
        /// Get invoice by id
        /// </summary>
        /// <param name="invoiceID"></param>
        /// <returns></returns>
        public static Invoice GetInvoiceByID(string invoiceNo)
        {
            try
            {
                XPQuery<Invoice> invoice = new XPQuery<Invoice>(Session.DefaultSession);
                var list = (from i in invoice
                            where (i.InvoiceNo == invoiceNo)
                            select i).First();
                return list;
            }
            catch (Exception)
            {
                return null;
            }
        }
        // create by Tuan
        //Get Previous buy price for specify supplier and product
        //
        public static List<PreviousPrice> GetPreviousBuyPrice(string supplierName, int ID)
        {
            XPQuery<InvoiceDetails> invoiceDetails = new XPQuery<InvoiceDetails>(new Session());
            var list = (from invdetails in invoiceDetails
                        where invdetails.InvoiceNo.SupplierID.SupplierName == supplierName && invdetails.StockID.ID.ID == ID && invdetails.InvoiceNo.Status == "P"
                        orderby invdetails.InvoiceNo.InvoiceDate descending
                        select new PreviousPrice(invdetails.InvoiceNo.InvoiceDate, invdetails.UnitPrice)).Take(3);
            return new List<PreviousPrice>(list.AsEnumerable<PreviousPrice>());

        }
    }
    
}
